<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
<title> RMCTutorial &lt; Mundo &lt; Foswiki</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="icon" href="/foswiki/pub/System/ProjectLogos/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="/foswiki/pub/System/ProjectLogos/favicon.ico" type="image/x-icon" />
<link rel="alternate" href="http://127.0.0.1/foswiki/bin/edit/Mundo/RMCTutorial?t=1295995544" type="application/x-wiki" title="edit RMCTutorial" />
<meta name="TEXT_NUM_TOPICS" content="Number of topics:" />
<meta name="TEXT_MODIFY_SEARCH" content="Modify search" />
<meta name="robots" content="noindex" /><link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/foswiki/bin/view/Mundo/WebRss" />
<style type="text/css" media="all">
@import url('style/base.css');
</style>
<style type="text/css" media="all">
@import url('style/layout.css');
@import url('style/style.css');
@import url('style/colors.css');
</style>
<style type="text/css" media="all">
@import url('style/column_left.css');
@import url('style/variant_foswiki_noframe.css');
</style><style type="text/css" media="all">
	/* Styles that are set using variables */
	.patternBookView .foswikiTopRow,
	.patternWebIndicator a img,
	.patternWebIndicator a:hover img {
		background-color:#efefef;
	}
	#patternTopBarContents { background-image:url(/foswiki/pub/System/PatternSkin/header5.gif); background-repeat:repeat-x;}
#patternTopBarContents { background-color:#ffffff;}
.patternBookView {
	border-color:#efefef;
}
.patternPreviewPage #patternMain {
	/* uncomment to set the preview image */
	/*background-image:url("/foswiki/pub/System/PreviewBackground/preview2bg.gif");*/
}
</style>
<style type="text/css" media="all">
@import url('style/print.css');
</style>
<!--[if IE]><style type="text/css" media="screen">
pre {
	height:1%;
	overflow-x:auto;
}
.foswikiAttachments,
.foswikiForm,
.foswikiHelp,
.foswikiPreviewArea,
.patternPreviewPage .foswikiForm,
.patternSigLine,
.patternToolBar,
.patternTop,
.patternTopicAction,
#patternSideBarContents .patternLeftBarPersonal,
#patternSideBarContents h2,
#patternSideBarContents li,
#patternTopBarButtons ul {
	height:1%;
}
#patternSideBarContents .patternLeftBarPersonal {
	width:100%;
}
.foswikiFormStep {
	height:100%;
}
#foswikiLogin,
.patternShadow {
	border:10px solid #fff;
	margin-top:10px;
	margin-bottom:10px;
	border:2px solid #ccc;
}
</style><![endif]-->
<!--[if gt IE 8 ]><style type="text/css" media="screen">
#foswikiLogin,
.patternShadow {
	border:10px solid #fff;
	margin-top:10px;
	margin-bottom:10px;
	box-shadow: 0 0 10px #ccc;
}
</style><![endif]-->
<meta name="foswiki.TWISTYANIMATIONSPEED" content="fast" /><!--TWISTYPLUGIN::META-->
<style type="text/css" media="all">
.foswikiTable {border-width:1px}
.foswikiTable .tableSortIcon img {padding-left:.3em; vertical-align:text-bottom}
.foswikiTable td {border-style:solid none; vertical-align:top}
.foswikiTable th {border-style:none solid; vertical-align:top; background-color:#d6d3cf; color:#000000}
.foswikiTable th a:link {color:#000000}
.foswikiTable th a:visited {color:#000000}
.foswikiTable th a:hover {color:#000000; background-color:#d6d3cf}
.foswikiTable th.foswikiSortedCol {background-color:#c4c1ba}
.foswikiTable tr.foswikiTableRowdataBg0 td {background-color:#ffffff}
.foswikiTable tr.foswikiTableRowdataBg0 td.foswikiSortedCol {background-color:#f7f7f6}
.foswikiTable tr.foswikiTableRowdataBg1 td {background-color:#f7f7f6}
.foswikiTable tr.foswikiTableRowdataBg1 td.foswikiSortedCol {background-color:#f0f0ee}
</style><!--TABLEPLUGIN_default-->
<meta name="foswiki.PUBURL" content="http://127.0.0.1/foswiki/pub" /> <!-- PUBURL -->
<meta name="foswiki.PUBURLPATH" content="/foswiki/pub" /> <!-- PUBURLPATH -->
<meta name="foswiki.SCRIPTSUFFIX" content="" /> <!-- SCRIPTSUFFIX -->
<meta name="foswiki.SCRIPTURL" content="http://127.0.0.1/foswiki/bin" /> <!-- SCRIPTURL -->
<meta name="foswiki.SCRIPTURLPATH" content="/foswiki/bin" /> <!-- SCRIPTURLPATH -->
<meta name="foswiki.SERVERTIME" content="25%20Jan%202011%20-%2023:45" /> <!-- SERVERTIME -->
<meta name="foswiki.SKIN" content="pattern" /> <!-- SKIN -->
<meta name="foswiki.SYSTEMWEB" content="System" /> <!-- SYSTEMWEB -->
<meta name="foswiki.TOPIC" content="RMCTutorial" /> <!-- TOPIC -->
<meta name="foswiki.USERNAME" content="guest" /> <!-- USERNAME -->
<meta name="foswiki.USERSWEB" content="Main" /> <!-- USERSWEB -->
<meta name="foswiki.WEB" content="Mundo" /> <!-- WEB -->
<meta name="foswiki.WIKINAME" content="WikiGuest" /> <!-- WIKINAME -->
<meta name="foswiki.WIKIUSERNAME" content="Main.WikiGuest" /> <!-- WIKIUSERNAME -->
<meta name="foswiki.NAMEFILTER" content="%5b%5cs%5c*%3f~%5e%5c%24%40%25%60%22'%26%3b%7c%3c%3e%5c%5b%5c%5d%23%5cx00-%5cx1f%5d" /> <!-- NAMEFILTER --><!--JQUERYPLUGIN::FOSWIKI::META-->
</head>
<body class="patternViewPage patternPrintPage">
<a name="PageTop"></a><div class="foswikiPage"><div id="patternScreen">
<div id="patternPageShadow">
<div id="patternPage">
<div id="patternOuter">
<div id="patternFloatWrap">
<div id="patternMain">
<div id="patternMainContents">
<div class="patternContent"><div class="foswikiTopic"> <h1><a name="Remote_Method_Calls"></a>  Remote Method Calls </h1>
<p />
A remote method call allows to call methods on remote services, with the abstraction of a local method call. In the following, an implementation of the chat example based on remote method calls is discussed.
<p />
<h2><a name="RMC_Interfaces"></a>  RMC Interfaces </h2>
<p />
Remote method calls rely on additional client and server stub classes that are generated by the precompiler. The metadata tag <code>@mcRemote</code> indicates that the precompiler should generate client and server stub classes for the following class or interface. It is usually preferable to generate stubs for interfaces instead of classes, because this allows to have the server-side implementation interchangeable.
<p />
For the Chat-service, we define the following interface:
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'>@mcRemote
<B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">interface</FONT></B> IChat {
  <B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> chatMessage(String msg);
}</pre><!-- end SyntaxHighlightingPlugin -->
<p />
<h2><a name="The_Server_Side"></a>  The Server Side </h2>
<p />
As server-side implementation we define a <code>Service</code> that implements the interface <code>IChat</code>. To receive chat messages, an instance of this service has to be connected to a <em>channel</em>. This way, other peers can send us messages.
<p />
To export an object on the server side, a subscriber must be connected to the server object:
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'>Subscriber sub = getSession().subscribe(<B><FONT COLOR="#BC8F8F">&quot;lan&quot;</FONT></B>, <B><FONT COLOR="#BC8F8F">&quot;chat_rmc&quot;</FONT></B>);
Signal.connect(sub, <B><FONT COLOR="#A020F0">this</FONT></B>);</pre><!-- end SyntaxHighlightingPlugin -->
<p />
The service now has to implement the method <code>chatMessage</code>, as defined in <code>IChat</code>. It can print the received message to the console:
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'><B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> chatMessage(String msg) {
  System.out.println(msg);
}</pre><!-- end SyntaxHighlightingPlugin -->
<p />
<h2><a name="The_client_side"></a>  The client side </h2>
<p />
A remote object can now be accessed by creating a client stub object and connecting the stub to a publisher:
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'>DoChatService stub = <B><FONT COLOR="#A020F0">new</FONT></B> DoChatService();
Publisher pub = getSession().publish(<B><FONT COLOR="#BC8F8F">&quot;lan&quot;</FONT></B>, <B><FONT COLOR="#BC8F8F">&quot;chat_rmc&quot;</FONT></B>);
Signal.connect(stub, pub);</pre><!-- end SyntaxHighlightingPlugin -->
<p />
<h2><a name="Sending_Messages"></a>  Sending Messages </h2>
<p />
Remote method calls can return a value or throw an Exception, just like regular methods. To make this behaviour work, MundoCore usually suspends your program at the method call until it gets a response from the remote method. This is called a <em>blocking call</em> and is also a behavior similar to regular method calls.
<p />
It is however possible, to use other call semantics with MundoCore. After all, if you don't expect an answer from a method invoked on another machine, why should you wait for that? In this example, we therefore use <em>one-way-calls</em> to publish chat messages:
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'>stub.chatMessage(ln, stub.ONEWAY);</pre><!-- end SyntaxHighlightingPlugin -->
<p />
The <code>chatMessage</code> method that takes the additional option parameter is generated by <code>mcc</code>. Another reason why it is necessary to use one-way-calls in this example is because blocking RMC-calls would not work with more than two clients (i.e., one client and more than one server), because each server would send a response message to the client. The client, ohn the other hand, only expects one such response.
<p />
<h2><a name="The_full_61RMCChat_61_program"></a>  The full <code>RMCChat</code> program </h2>
<p />
<code><b>samples/chat/rmc/src/RMCChat.java</b></code>
<p />
<p />
<!-- SyntaxHighlightingPlugin --><pre class='syntaxHighlightingPlugin'><B><FONT COLOR="#A020F0">import</FONT></B> java.io.BufferedReader;
<B><FONT COLOR="#A020F0">import</FONT></B> java.io.InputStreamReader;
<B><FONT COLOR="#A020F0">import</FONT></B> org.mundo.rt.Mundo;
<B><FONT COLOR="#A020F0">import</FONT></B> org.mundo.rt.Service;
<B><FONT COLOR="#A020F0">import</FONT></B> org.mundo.rt.Signal;

<B><FONT COLOR="#A020F0">class</FONT></B> ChatService <B><FONT COLOR="#A020F0">extends</FONT></B> Service <B><FONT COLOR="#A020F0">implements</FONT></B> IChat {
  <B><FONT COLOR="#A020F0">private</FONT></B> <B><FONT COLOR="#A020F0">static</FONT></B> <B><FONT COLOR="#A020F0">final</FONT></B> String CHANNEL_NAME = <B><FONT COLOR="#BC8F8F">&quot;chat_rmc&quot;</FONT></B>;
  <B><FONT COLOR="#A020F0">private</FONT></B> <B><FONT COLOR="#A020F0">static</FONT></B> <B><FONT COLOR="#A020F0">final</FONT></B> String ZONE_NAME = <B><FONT COLOR="#BC8F8F">&quot;lan&quot;</FONT></B>;
  DoIChat doChat;
 
  <B><FONT COLOR="#A020F0">public</FONT></B> ChatService() {
  }
  <B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> init() {
    <B><FONT COLOR="#A020F0">try</FONT></B> {
      <I><FONT COLOR="#B22222">// connect channel to this object to receive chat messages
</FONT></I>      Signal.connect(getSession().subscribe(ZONE_NAME, CHANNEL_NAME), <B><FONT COLOR="#A020F0">this</FONT></B>);

      <I><FONT COLOR="#B22222">// connect DoIChat stub to channel to send chat messages
</FONT></I>      doChat = <B><FONT COLOR="#A020F0">new</FONT></B> DoIChat();
      Signal.connect(doChat, getSession().publish(ZONE_NAME, CHANNEL_NAME));
    }
    <B><FONT COLOR="#A020F0">catch</FONT></B>(Exception x) {
      x.printStackTrace();
    }
  }
  <B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> run() {
    <B><FONT COLOR="#A020F0">try</FONT></B> {
      BufferedReader r=<B><FONT COLOR="#A020F0">new</FONT></B> BufferedReader(<B><FONT COLOR="#A020F0">new</FONT></B> InputStreamReader(System.in));
      String ln;
      <B><FONT COLOR="#A020F0">while</FONT></B> ( (ln=r.readLine())!=<B><FONT COLOR="#A020F0">null</FONT></B> &amp;&amp; !ln.equals(<B><FONT COLOR="#BC8F8F">&quot;.&quot;</FONT></B>) )
        doChat.chatMessage(ln, doChat.ONEWAY);
    }
    <B><FONT COLOR="#A020F0">catch</FONT></B> (Exception x) {
      x.printStackTrace();
    }
  }  
  <B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> chatMessage(String msg) <I><FONT COLOR="#B22222">/*IChat*/</FONT></I> {
    System.out.println(msg);
  }
}

<B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">class</FONT></B> RMCChat {
  <B><FONT COLOR="#A020F0">public</FONT></B> <B><FONT COLOR="#A020F0">static</FONT></B> <B><FONT COLOR="#A020F0">void</FONT></B> main(String args[]) {
    Mundo.init();
    ChatService cs=<B><FONT COLOR="#A020F0">new</FONT></B> ChatService();
    Mundo.registerService(cs);
    cs.run();
    Mundo.shutdown();
  }
}</pre><!-- end SyntaxHighlightingPlugin -->
<p />
</div></div><!-- /patternContent-->
</div></div></div></div></div></div></div></div>
</body></html>
